/* 
 * File:   matrix.h
 * Author: gustavo
 *
 * Created on January 6, 2012, 2:44 AM
 */

#ifndef MATRIX_H
#define	MATRIX_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <util/types.h>
#include <util/mem.h>

#include "../object/object.h"

#define IMP_MATRIX_TYPE			( imp_matrix_get_class() )
#define IMP_IS_MATRIX(obj)		( imp_object_is_from_class (obj, imp_matrix_get_class ()) )
#define IMP_MATRIX(obj)			IMP_OBJECT_CAST (obj, ImpMatrix, imp_matrix_get_class () )
#define IMP_MATRIX_CLASS(klass)	IMP_OBJECT_CLASS_CAST (klass, ImpMatrixClass, imp_matrix_get_class () )

	/* ====================================================================== */
	typedef struct _imp_matrix ImpMatrix;
	typedef struct _imp_matrix_class ImpMatrixClass;

	struct _imp_matrix {
		extends(ImpObject);

		int rows;
		int columns;
		int size;
		real * data;
	};

	struct _imp_matrix_class {
		extends(ImpObjectClass);

	};

	ImpObjectClass * imp_matrix_get_class(void);
	boolean imp_matrix_set_data(ImpMatrix * mat, void * data, int rows, int columns);
	boolean imp_matrix_constructor(ImpMatrix * mat, int rows, int columns);
	ImpMatrix * imp_matrix_new(int rows, int columns);

	/* ====================================================================== */
#define MAT( Mat, r, c) (Mat)->data[ c + r*(Mat)->columns ]
#define imp_matrix_idx( mat, x, y) ( (int)(x) + ( (int)(y)*(mat)->columns) )
	ImpMatrix * imp_matrix_new_identity(int dim);
	ImpMatrix * imp_matrix_new_ones(int rows, int columns);
	ImpMatrix * imp_matrix_new_rand(int rows, int columns, real min, real max);
	ImpMatrix * imp_matrix_new_copy(ImpMatrix * M);
	void imp_matrix_clear(ImpMatrix * mat);
	void imp_matrix_print(ImpMatrix * M);
	ImpMatrix * imp_matrix_cut(ImpMatrix * A, int r0, int c0, int r1, int c1);
	void imp_matrix_normailze(ImpMatrix * A, real min, real max);

	void imp_matrix_get_normailzed(ImpMatrix * A, ImpMatrix ** B, real min, real max);
	//void imp_matrix_sub(ImpMatrix * A, ImpMatrix * B, ImpMatrix ** Sub);

#ifdef	__cplusplus
}
#endif

#endif	/* MATRIX_H */

